﻿using System.ComponentModel;
using IdeaBlade.EntityModel;

namespace SWTORLogDb.Entities
{
    /// <summary>
    /// Helper class to encapsulate several common properties of the EntityAspect
    /// </summary>
    public class EntityFacts : INotifyPropertyChanged
    {
        private readonly EntityAspect _entityAspect;

        /// <summary>
        /// Initializes a new instance of the <see cref="EntityFacts" /> class.
        /// </summary>
        /// <param name="entity">The entity.</param>
        public EntityFacts(object entity)
        {
            _entityAspect = EntityAspect.Wrap(entity);
            _entityAspect.PropertyChanged +=
                (s, args) => RaiseEntityFactsPropertyChanged(string.Empty);
            _entityAspect.EntityPropertyChanged += EntityAspectOnEntityPropertyChanged;
        }

        private void EntityAspectOnEntityPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
        {
            RaisePropertyChanged("HasChanges");
        }

        /// <summary>
        /// Gets a value indicating whether this instance has changes.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance has changes; otherwise, <c>false</c>.
        /// </value>
        public bool HasChanges
        {
            get { return _entityAspect.HasChanges(); }
        }

        /// <summary>
        /// Gets the state of the entity.
        /// </summary>
        /// <value>
        /// The state of the entity.
        /// </value>
        public EntityState EntityState
        {
            get { return _entityAspect.EntityState; }
        }

        /// <summary>
        /// Gets a value indicating whether this instance is null entity.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance is null entity; otherwise, <c>false</c>.
        /// </value>
        public bool IsNullEntity
        {
            get { return _entityAspect.IsNullEntity; }
        }

        /// <summary>
        /// Gets a value indicating whether this instance is a pending entity.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance is a pending entity; otherwise, <c>false</c>.
        /// </value>
        public bool IsPendingEntity
        {
            get { return _entityAspect.IsPendingEntity; }
        }

        /// <summary>
        /// Gets a value indicating whether this instance is a null or pending entity.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance is a null or pending entity; otherwise, <c>false</c>.
        /// </value>
        public bool IsNullOrPendingEntity
        {
            get { return _entityAspect.IsNullOrPendingEntity; }
        }

        /// <summary>
        /// Gets a value indicating whether this instance has errors.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance has errors; otherwise, <c>false</c>.
        /// </value>
        public bool HasErrors
        {
            get { return _entityAspect.ValidationErrors.HasErrors; }
        }

        /// <summary>
        /// Gets the validation errors.
        /// </summary>
        /// <value>
        /// The validation errors.
        /// </value>
        public EntityAspect.VerifierErrorsCollection ValidationErrors
        {
            get { return _entityAspect.ValidationErrors; }
        }

        /// <summary>
        /// Gets the entity aspect.
        /// </summary>
        /// <value>
        /// The entity aspect.
        /// </value>
        protected internal EntityAspect EntityAspect
        {
            get { return _entityAspect; }
        }

        /// <summary>
        /// Raises the property changed event.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        public void RaisePropertyChanged(string propertyName)
        {
            _entityAspect.ForcePropertyChanged(new PropertyChangedEventArgs(propertyName));
        }

        /// <summary>
        /// Occurs when [entity property changed].
        /// </summary>
        public event PropertyChangedEventHandler EntityPropertyChanged
        {
            add { _entityAspect.EntityPropertyChanged += value; }
            remove { _entityAspect.EntityPropertyChanged -= value; }
        }

        /// <summary>
        /// Occurs when [property changed].
        /// </summary>
        event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
        {
            add { EntityFactsPropertyChanged += value; }
            remove { EntityFactsPropertyChanged -= value; }
        }
        /// <summary>
        /// Occurs when [entity facts property changed].
        /// </summary>
        protected event PropertyChangedEventHandler EntityFactsPropertyChanged;

        /// <summary>
        /// Raises the entity facts property changed.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        protected void RaiseEntityFactsPropertyChanged(string propertyName)
        {
            if (null == EntityFactsPropertyChanged) return;
            EntityFactsPropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
